package org.aspire.core.console;

import org.aspire.core.Console;
import org.aspire.core.Game;
import org.aspire.core.game.PCGame;
import org.aspire.core.loop.PreciseLoopController;
import org.aspire.core.loop.StandardLoopController;
import org.aspire.core.sys.GSystem;
import org.aspire.core.sys.GameException;
import org.aspire.data.renderer.JavaStandardRenderer;
import org.aspire.data.renderer.OpenGLRenderer;
import org.aspire.graphics.display.JavaStandardDisplay;
import org.aspire.graphics.display.OpenGLDisplay;
import org.aspire.io.FileIO;

/******************************************************************************
 * A console that specializes in loading and managing games made for the
 * Personal Computer (PC) platform.
 * 
 * @author JPACarabuena
 *****************************************************************************/
public class PCConsole implements Console {

	// ========================================================================
	// Constants
	// ========================================================================

	// ========================================================================
	// Static Methods
	// ========================================================================
	
	// ========================================================================
	// Fields
	// ========================================================================
	
	// ========================================================================
	// Constructors
	// ========================================================================
	
	// ========================================================================
	// Getters & Setters
	// ========================================================================

	// ========================================================================
	// Override Methods
	// ========================================================================
	
	@Override
	public void setup(Game game) throws GameException {
		if(game instanceof PCGame) {
			this.loadSubSystems(game);
			Console.ENGINE.mountGame(game);
		} else {
			throw new GameException("Uncompatible Game and Console.");
		}
	}

	@Override
	public void start() throws GameException {
		if(!Console.ENGINE.isEmpty()) {
			Console.ENGINE.run();
		} else {
			throw new GameException("Couldn't Find Any Game to Execute.");
		}
	}

	@Override
	public void pause() {
		Console.ENGINE.pause();
	}

	@Override
	public void resume() {
		Console.ENGINE.resume();
	}

	@Override
	public void stop() {
		Console.ENGINE.stop();
	}

	@Override
	public void loadSubSystems(Game game) {
		PCGame pcgame = (PCGame) game;
		
		/* The Engine's Display Subsystem */
		if(Console.ENGINE.display == null) {
			if(pcgame.isOpenGLEnabled()) {
				Console.ENGINE.display = new OpenGLDisplay(
						Console.ENGINE, pcgame);
			} else {
				Console.ENGINE.display = new JavaStandardDisplay(
						Console.ENGINE, pcgame);
			}
		}
		
		/* The Engine's FPS Regulator Subsystem */
		if(Console.ENGINE.controller == null) {
			if(pcgame.isPreciseLoopControllerEnabled()) {
				Console.ENGINE.controller = new PreciseLoopController();
			} else {
				Console.ENGINE.controller = new StandardLoopController();
			}
			
			Console.ENGINE.controller.setFPS(
					pcgame.getFPS());
			Console.ENGINE.controller.setResolution(
					pcgame.getResolution());
			Console.ENGINE.controller.enableRegulate(
					pcgame.isProcessRegulated());
			Console.ENGINE.controller.enableSmoothUpdate(
					pcgame.isUpdateSmooth());
		}
		
		/* The Engine's Graphics & Audio Renderer */
		if(Console.ENGINE.renderer == null) {
			if(pcgame.isOpenGLEnabled()) {
				Console.ENGINE.renderer = new OpenGLRenderer();
			} else {
				Console.ENGINE.renderer = new JavaStandardRenderer();
			}
		}
		
		/* The Engine's File IO Manager */
		if(Console.ENGINE.fileIO == null) {
			Console.ENGINE.fileIO = new FileIO(pcgame.getBaseClass());
		}
		
		/* System-wide Configurations */
		GSystem.SCREEN_RESOLUTION = pcgame.getScreenDisplaySize();
	}

	// ========================================================================
	// Methods
	// ========================================================================
	
	// ========================================================================
	// Inner & Anonymous Classes
	// ========================================================================
}